#include "VxIrrLib.h"

//============================================================================
//! get height of model ( bbox height )
irr::f32 GetModelHeight( irr::scene::ISceneNode * poNode )
{
	irr::core::aabbox3d<irr::f32> Box = poNode->getBoundingBox();

	irr::core::vector3df v3fDim = Box.MaxEdge - Box.MinEdge;
	return v3fDim.Y;
}
//============================================================================
//! get width of model ( bbox  greatest of width or length )
irr::f32 GetModelWidth( irr::scene::ISceneNode * poNode )
{
	irr::core::aabbox3d<irr::f32> Box = poNode->getBoundingBox();

	irr::core::vector3df v3fDim = Box.MaxEdge - Box.MinEdge;
	return max( v3fDim.X, v3fDim.Z );
}
//============================================================================
//! sets up a quad mesh of given dimenstion
void SetupQuadMesh( irr::scene::SMeshBuffer &mesh, irr::f32 f32Width )
{
	irr::f32 f32HalfWidth = f32Width/2.0f;
    mesh.Vertices.set_used(4); 
    mesh.Indices .set_used(6); 

    irr::video::SColor white(255, 255, 255, 255); 

    mesh.Vertices[0] = irr::video::S3DVertex(-f32HalfWidth, -f32HalfWidth, 0.f, 0.f, 0.f, 1.f, white, 0.f, 1.f); 
    mesh.Vertices[1] = irr::video::S3DVertex(-f32HalfWidth,  f32HalfWidth, 0.f, 0.f, 0.f, 1.f, white, 0.f, 0.f); 
    mesh.Vertices[2] = irr::video::S3DVertex( f32HalfWidth,  f32HalfWidth, 0.f, 0.f, 0.f, 1.f, white, 1.f, 0.f); 
    mesh.Vertices[3] = irr::video::S3DVertex( f32HalfWidth, -f32HalfWidth, 0.f, 0.f, 0.f, 1.f, white, 1.f, 1.f); 
    mesh.Indices[0] = 0; 
    mesh.Indices[1] = 1; 
    mesh.Indices[2] = 2; 
    mesh.Indices[3] = 2; 
    mesh.Indices[4] = 3; 
    mesh.Indices[5] = 0; 

    mesh.getMaterial().Lighting = false; 
    //mesh.getMaterial().BackfaceCulling = false; 
    //mesh.getMaterial().Wireframe = true; 
	mesh.getMaterial().MaterialType = irr::video::EMT_TRANSPARENT_ALPHA_CHANNEL; 
}
//============================================================================
//! gets camera heading.. assumes camera is child of root
irr::f32 GetCameraHeading( irr::scene::ICameraSceneNode* camera )
{
      //BRJ correct way to get heading posted by Vitek 
      irr::core::vector3df fore(0, 0, 1); 
      camera->getAbsoluteTransformation().rotateVect(fore); 
      irr::core::vector3df rot1 = fore.getHorizontalAngle(); 
	  return rot1.Y;
}

//============================================================================
//! given a triangle with corners p1,p2,p3 ,UVs: uv1,uv2,uv3 and a point on triangle called newp then return the uv coordinates of the point
RCODE CalcUVCoordFromPointInTriangle(	irr::core::vector3df& v3fTriPoint1,		// triangle vertex point 1
										irr::core::vector3df& v3fTriPoint2,		// triangle vertex point 2
										irr::core::vector3df& v3fTriPoint3,		// triangle vertex point 3
										irr::core::vector3df& v3fPointInTri,	// point in triangle
										irr::core::vector2df& v2fUv1,			// uv coord of triangle point 1
										irr::core::vector2df& v2fUv2,			// uv coord of triangle point 2
										irr::core::vector2df& v2fUv3,			// uv coord of triangle point 3
										irr::core::vector2df& v2fRetUvCoord )	// return uv coordinate
{
	// calc vectors from triangle points
	irr::core::vector3df v0 = v3fTriPoint3 - v3fTriPoint1;
    irr::core::vector3df v1 = v3fTriPoint2 - v3fTriPoint1;
    irr::core::vector3df v2 = v3fPointInTri - v3fTriPoint1;

    // calc dot products of vectors
    float dot00 = v0.dotProduct( v0 );
    float dot01 = v0.dotProduct( v1 );
    float dot02 = v0.dotProduct( v2 );
    float dot11 = v1.dotProduct( v1 );
    float dot12 = v1.dotProduct( v2 );

    // calculate barycentric coordinates
    float invDenom = 1 / ( dot00 * dot11 - dot01 * dot01 );
    float u = ( dot11 * dot02 - dot01 * dot12 ) * invDenom;
    float v = ( dot00 * dot12 - dot01 * dot02 ) * invDenom;
						
	if( (u > 0) && (v > 0) && (u + v < 1) )
	{
		// point was in the triangle
		irr::core::vector2df t2 = v2fUv2-v2fUv1;
		irr::core::vector2df t1 = v2fUv3-v2fUv1;

		// return the calculated uv coords
		v2fRetUvCoord = v2fUv1 + t1*u + t2*v;
		return 0;
	}
	return -1; // point was not in the triangle

}

